/*
 * Copyright (c) 2018 - 2028. www.vtuzx.com Inc. All Rights Reserved
 */
package com.vtuzx.kingdee.xqc_api.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.mongodb.client.result.UpdateResult;
import com.vtuzx.core.VtuzxException;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.bean.dto.VtuzxPage;
import com.vtuzx.core.bean.dto.VtuzxToken;
import com.vtuzx.core.constant.IVtuzxConst;
import com.vtuzx.core.utils.VtuzxUtil;
import com.vtuzx.fast.service.IFastSettingService;
import com.vtuzx.fast.utils.FastUtil;
import com.vtuzx.kingdee.xqc_api.dao.ConfigDao;
import com.vtuzx.kingdee.xqc_api.service.*;
import com.vtuzx.kingdee.xqc_core.bean.VtuzxArrayList;
import com.vtuzx.kingdee.xqc_core.constant.*;
import com.vtuzx.kingdee.xqc_core.dao.*;
import com.vtuzx.kingdee.xqc_core.service.IJiKeYunApiService;
import com.vtuzx.kingdee.xqc_core.service.IVtuzxBasicService;
import com.vtuzx.web.service.IVtuzxWebService;
import org.aspectj.weaver.tools.Trace;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

@Service
public class XqcIfServiceImpl implements IXqcIfService {

    /** Logger */
    private static final Logger _logger = LoggerFactory.getLogger(XqcIfServiceImpl.class);

    @Autowired
    IFastSettingService settingService;

    @Autowired
    IXqcPurchaseService purchaseService;

    @Autowired
    ConfigDao configDao;

    @Autowired
    InventoryDetailDao inventoryDetailDao;

    @Autowired
    InventoryDao inventoryDao;

    @Autowired
    MaterialDao materialDao;

    @Autowired
    PurColDetailDao purColDetailDao;

    @Autowired
    PrdColDetailDao prdColDetailDao;

    @Autowired
    OtherColDetailDao otherColDetailDao;

    @Autowired
    IXqcProduceService produceService;

    @Autowired
    IXqcOtherService otherService;

    @Autowired
    IXqcTrayService trayService;

    @Autowired
    OperationHistoryDao operationHistoryDao;

    @Autowired
    TrayDao trayDao;

    @Autowired
    StockDao stockDao;

    @Autowired
    TraceabilityCodeDetailDao traceabilityCodeDetailDao;

    @Autowired
    TraceabilityCodeDao traceabilityCodeDao;

    @Autowired
    private IVtuzxWebService webService;

    @Autowired
    private TraceabilityHistoryDao traceabilityHistoryDao;

    @Autowired
    private IJiKeYunApiService jiKeYunApiService;

    @Autowired
    private StoreTokenDao storeTokenDao;

    @Autowired
    private IXqcTraceBackService iXqcTraceBackService;

    @Override
    public void bindBoxRfid(String boxNo, String rfid, long timestamp, String sign, boolean checkSign) throws VtuzxException {
        _logger.info(String.format("RFID绑码开始, boxNo:%s, rfid:%s, timestamp:%d, sign:%s", boxNo, rfid, timestamp, sign));
        // 验签
        checkSign(sign, timestamp, boxNo, rfid);
        _logger.info(String.format("RFID绑码验签通过, boxNo:%s, rfid:%s, timestamp:%d, sign:%s", boxNo, rfid, timestamp, sign));
        if (checkSign) {
            return;
        }
        if (boxNo.startsWith("T")) {
            trayService.bindTrayRfid(boxNo, rfid.toUpperCase());
            operationHistoryDao.addHistory("IF", OperationType.rfid_bind_tpgl, String.format("RFID:[%s],箱号:[%s],", rfid, boxNo));
        } else {
            boolean isGetRfid = getRfid(boxNo, rfid);
            if (!isGetRfid) {
                if (boxNo.startsWith("A01")) {
                    // 采购收货操作
                    purchaseService.bindPurColBoxRfid(boxNo, rfid);
                    operationHistoryDao.addHistory("IF", OperationType.rfid_bind_cgsh, String.format("RFID:[%s],箱号:[%s],", rfid, boxNo));
                } else if (boxNo.startsWith("A02")) {
                    // 车间收货操作
                    produceService.bindPrdColBoxRfid(boxNo, rfid);
                    operationHistoryDao.addHistory("IF", OperationType.rfid_bind_cjrk, String.format("RFID:[%s],箱号:[%s],", rfid, boxNo));
                } else if (boxNo.startsWith("A03")) {
                    // 其他收货操作
                    otherService.bindOtherOutBoxRfid(boxNo, rfid);
                    operationHistoryDao.addHistory("IF", OperationType.rfid_bind_qtsh, String.format("RFID:[%s],箱号:[%s],", rfid, boxNo));
                } else {
                    _logger.info(String.format("RFID绑码失败, 箱码格式错误, boxNo:%s, rfid:%s, timestamp:%d, sign:%s", boxNo, rfid, timestamp, sign));
                    throw new VtuzxException(IXqcConst.Msg_E_XQC_box_err, boxNo);
                }
            } else {
                operationHistoryDao.addHistory("IF", OperationType.rfid_bind_jskc, String.format("RFID:[%s],箱号:[%s],", rfid, boxNo));
            }
        }

        _logger.info(String.format("RFID绑码完成, boxNo:%s, rfid:%s, timestamp:%d, sign:%s", boxNo, rfid, timestamp, sign));
    }

    @Override
    public void recordRfidInOut(String type, String palletRfid, List<String> rfids, long timestamp, String sign, boolean checkSign) throws VtuzxException {
        String rfidStr = StringUtils.collectionToCommaDelimitedString(rfids);
        _logger.info(String.format("RFID出入库开始, type:%s, palletRfid:%s, rfids:%s, timestamp:%d, sign:%s", type, palletRfid, rfidStr, timestamp, sign));
        // 验签
        checkSign(sign, timestamp, palletRfid, rfidStr, type);
        _logger.info(String.format("RFID出入库验签通过, type:%s, palletRfid:%s, rfids:%s, timestamp:%d, sign:%s", type, palletRfid, rfidStr, timestamp, sign));
        if (checkSign) {
            return;
        }
        if ("in".equals(type)) {
            operationHistoryDao.addHistory("IF", OperationType.rfid_in,
                    String.format("RFID入库, 托盘:[%s],箱号:[%s]", palletRfid, rfidStr));
        } else {
            operationHistoryDao.addHistory("IF", OperationType.rfid_out,
                    String.format("RFID出库, 托盘:[%s],箱号:[%s]", palletRfid, rfidStr));
        }
        _logger.info(String.format("RFID出入库完成, type:%s, palletRfid:%s, rfids:%s, timestamp:%d, sign:%s", type, palletRfid, rfidStr, timestamp, sign));
    }

    @Override
    public VtuzxMap getMaterialByBox(String boxNo, long timestamp, String sign, boolean checkSign) throws VtuzxException {
        _logger.info(String.format("RFID获取物料开始, boxNo:%s, timestamp:%d, sign:%s", boxNo, timestamp, sign));
        // 验签
        checkSign(sign, timestamp, boxNo);
        _logger.info(String.format("RFID获取物料验签通过, boxNo:%s, timestamp:%d, sign:%s", boxNo, timestamp, sign));
        if (checkSign) {
            return null;
        }
        VtuzxMap inventoryBox = getInventoryBox(boxNo);
        if (inventoryBox.size() == 0) {
            if (boxNo.startsWith("A01")) {
                // 采购收货操作
                _logger.info(String.format("RFID获取物料完成(采购收货), boxNo:%s, timestamp:%d, sign:%s", boxNo, timestamp, sign));
                return purchaseService.getPurColMaterialForBind(boxNo);
            } else if (boxNo.startsWith("A02")) {
                // 采购收货操作
                _logger.info(String.format("RFID获取物料完成(车间入库), boxNo:%s, timestamp:%d, sign:%s", boxNo, timestamp, sign));
                return produceService.getPrdColMaterialForBind(boxNo);
            } else if (boxNo.startsWith("A03")) {
                // 采购收货操作
                _logger.info(String.format("RFID获取物料完成(其他收货), boxNo:%s, timestamp:%d, sign:%s", boxNo, timestamp, sign));
                return otherService.getOtherOutMaterialForBind(boxNo);
            } else {
                _logger.info(String.format("RFID获取物料失败, 箱码格式错误, boxNo:%s, timestamp:%d, sign:%s", boxNo, timestamp, sign));
                throw new VtuzxException(IXqcConst.Msg_E_XQC_box_err, boxNo);
            }
        }
        return inventoryBox;
    }

    private VtuzxMap getInventoryBox(String boxNo) throws VtuzxException {
        _logger.info(String.format("即时库存查询箱号[%s]", boxNo));
        Document boxDoc = inventoryDetailDao.findOne(Criteria.where("boxNo").is(boxNo));
        VtuzxMap map = new VtuzxMap();
        if (!VtuzxUtil.isEmpty(boxDoc)) {
            String status = VtuzxUtil.getString(boxDoc, "status");
            if (!"in".equals(status)) {
                throw new VtuzxException(IXqcConst.Msg_E_XQC_box_not_exist, boxNo);
            }
            ObjectId _inventoryId = VtuzxUtil.getObject(boxDoc, "_inventoryId");
            Document inventoryDoc = inventoryDao.findById(_inventoryId);
            String materialNo = VtuzxUtil.getString(inventoryDoc, "materialNo");
            String batchNo = VtuzxUtil.getString(inventoryDoc, "batchNo");
            Document materialDoc = materialDao.findOne(Criteria.where("fNumber").is(materialNo));
            String fName = VtuzxUtil.getString(materialDoc, "fName");
            String fSpecification = VtuzxUtil.getString(materialDoc, "fSpecification");
            String unit = VtuzxUtil.getString(materialDoc, "fBaseUnitIdNumber");
            double count = VtuzxUtil.getDouble(boxDoc, "count");
            map.append("materialNo", materialNo)
                    .append("materialName", fName)
                    .append("materialSpec", fSpecification)
                    .append("batchNo", batchNo)
                    .append("unit", unit)
                    .append("count", count)
                    .append("supplierName", VtuzxUtil.getString(boxDoc, "supplierName"))
                    .append("instockDate", VtuzxUtil.formatYmdHmsF(VtuzxUtil.getObject(boxDoc, "createTime")))
                    .append("produceDate", VtuzxUtil.getString(boxDoc, "produceDate"))
                    .append("exp", VtuzxUtil.getInt(boxDoc, "exp"));
        }
        return map;
    }

    private boolean getRfid(String boxNo, String rfid) throws VtuzxException {
        boolean existStatus = false;
        Document inventoryDetail = inventoryDetailDao.findOne(Criteria.where("boxNo").is(boxNo).and("status").and("in"));
        if (!VtuzxUtil.isEmpty(inventoryDetail)) {
            ObjectId id = VtuzxUtil.getObject(inventoryDetail, IVtuzxConst.Key__id);
            Document inventoryDoc = inventoryDetailDao.findOne(Criteria.where("rfid").is(rfid).and("status").is("in"));
            if (!VtuzxUtil.isEmpty(inventoryDoc)) {
                throw new VtuzxException("即时库存存在相同rfid");
            }
            Document purDoc = purColDetailDao.findOne(Criteria.where("rfid").is(rfid).and("inStock").ne(true));
            if (!VtuzxUtil.isEmpty(purDoc)) {
                throw new VtuzxException("采购收货存在相同rfid");
            }
            Document prdDoc = prdColDetailDao.findOne(Criteria.where("rfid").is(rfid).and("inStock").ne(true));
            if (!VtuzxUtil.isEmpty(prdDoc)) {
                throw new VtuzxException("车间收货存在相同rfid");
            }
            Document otherDoc = otherColDetailDao.findOne(Criteria.where("rfid").is(rfid).and("inStock").ne(true));
            if (!VtuzxUtil.isEmpty(otherDoc)) {
                throw new VtuzxException("其他收货存在相同rfid");
            }
            inventoryDetailDao.updateById(id, new Document("rfid", rfid));
            existStatus = true;
        }
        return existStatus;
    }

    /**
     * 验签
     *
     * @param sign 签名
     * @param timestamp 时间戳(s)
     * @param valueList 校验值
     * @throws VtuzxException 异常信息
     */
    private void checkSign(String sign, long timestamp, String... valueList) throws VtuzxException {
        VtuzxMap sysParamMap = settingService.getParameters(new VtuzxMap("keys", new VtuzxArrayList<>("if_timeout", "if_secret")));
        VtuzxMap timeoutMap = VtuzxUtil.getObject(sysParamMap, "if_timeout");
        VtuzxMap secretMap = VtuzxUtil.getObject(sysParamMap, "if_secret");
        if (timeoutMap == null || secretMap == null) {
            throw new VtuzxException(IXqcConst.Msg_E_system);
        }
        long ifTimeout = VtuzxUtil.getInt(timeoutMap, "value");
        String secret = VtuzxUtil.getString(secretMap, "value");
        if (ifTimeout == 0 || VtuzxUtil.isEmpty(secret)) {
            throw new VtuzxException(IXqcConst.Msg_E_system);
        }

        long curr = System.currentTimeMillis() / 1000;
        if (ifTimeout < curr - timestamp) {
            throw new VtuzxException(IXqcConst.Msg_E_XQC_if_timeout);
        }
        // 时间戳 + 正文 + 秘钥
        // MD5(拼接字符串)
        StringBuilder temp = new StringBuilder(String.valueOf(timestamp));
        for(String value: valueList) {
            temp.append(value);
        }
        temp.append(secret);
        try {
            if (!sign.equals(VtuzxUtil.md5(URLEncoder.encode(temp.toString(), "UTF-8")))) {
                throw new VtuzxException(IXqcConst.Msg_E_XQC_sign_err);
            }
        } catch (UnsupportedEncodingException e) {
            throw new VtuzxException(IXqcConst.Msg_E_XQC_sign_err);
        }
    }

    /**
     * 验签
     *
     * @param sign 签名
     * @param timestamp 时间戳(s)
     * @throws VtuzxException 异常信息
     */
    private void checkSign(String sign, long timestamp, String box_no, String trace_back) throws VtuzxException {
        VtuzxMap sysParamMap = settingService.getParameters(new VtuzxMap("keys", new VtuzxArrayList<>("if_timeout", "if_secret")));
        VtuzxMap timeoutMap = VtuzxUtil.getObject(sysParamMap, "if_timeout");
        VtuzxMap secretMap = VtuzxUtil.getObject(sysParamMap, "if_secret");
        if (timeoutMap == null || secretMap == null) {
            throw new VtuzxException(IXqcConst.Msg_E_system);
        }
        long ifTimeout = VtuzxUtil.getInt(timeoutMap, "value");
        String secret = VtuzxUtil.getString(secretMap, "value");
        if (ifTimeout == 0 || VtuzxUtil.isEmpty(secret)) {
            throw new VtuzxException(IXqcConst.Msg_E_system);
        }

        long curr = System.currentTimeMillis() / 1000;
        if (ifTimeout < curr - timestamp) {
            throw new VtuzxException(IXqcConst.Msg_E_XQC_if_timeout);
        }
        // 时间戳 + 正文 + 秘钥
        // MD5(拼接字符串)
        StringBuilder temp = new StringBuilder(String.valueOf(timestamp));
        temp.append(box_no);
        temp.append(trace_back);
        temp.append(secret);
        if (!sign.equals(VtuzxUtil.md5(temp.toString()))) {
            throw new VtuzxException(IXqcConst.Msg_E_XQC_sign_err);
        }
    }


    @Override
    public void trayInventory(List<String> rfidList, long timestamp, String sign, String ip, boolean checkSignOnly,boolean highlight) throws VtuzxException {
        String rfidStr = StringUtils.collectionToCommaDelimitedString(rfidList);
        _logger.info(String.format("托盘盘点开始, rfid:%s, timestamp:%d, sign:%s, 低电量:%b", rfidStr, timestamp, sign, highlight));
        // 验签
        checkSign(sign, timestamp, ip, rfidStr);
        _logger.info(String.format("托盘盘点验签通过, rfid:%s, timestamp:%d, sign:%s", rfidStr, timestamp, sign));
        List<String> rList = new ArrayList<>();
        for (String rfid: rfidList) {
            rList.add(rfid.toUpperCase());
        }

        if(highlight){//true是低电量，fasle是高电量
            trayDao.updateMany(Criteria.where("rfid").in(rList), new Document("lastInventoryTime", new Date()).append("ip", ip)
                    .append("highlight","low"));
        } else {
            trayDao.updateMany(Criteria.where("rfid").in(rList), new Document("lastInventoryTime", new Date())
                    .append("ip", ip).append("highlight","hight"));
        }

        //如果托盘的最后修改时间小于当前时间减去两个小时说明肯定没电了，没有在发送过信息，改成未连接的状态
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDateTime minDate = localDateTime.minusHours(2);
        Date date1 = Date.from(minDate.atZone(ZoneId.systemDefault()).toInstant());
        //先判断有没有，有的话在修改
        Long count = trayDao.count(Criteria.where("lastInventoryTime").lt(date1));
        if (count > 0 ){
            UpdateResult updateResult = trayDao.updateMany(Criteria.where("lastInventoryTime")
                    .lt(date1), new Document("highlight", "connect"));
        }
        //创建一个四位随机数，把电量都改成高电量
        //判断托盘的创建时间跟当前时间大于两年的话再改
//        String str = "0123456789";
//        StringBuilder ranNum = new StringBuilder(6);
//        ranNum.append(1);
//        ranNum.append(0);
//        for (int i = 0;i < 4;i++){
//            char ch = str.charAt(new Random().nextInt(str.length()));
//            ranNum.append(ch);
//        }
//        String number = new String(ranNum);
//        _logger.info(String.format("随机数为%s",number));
//        Document trayDoc = trayDao.findOne(Criteria.where("trayNumber").regex(number));
//        if (!VtuzxUtil.isEmpty(trayDoc)){
//            Date trayDate = VtuzxUtil.getObject(trayDoc,"createTime");
//            Calendar trayCal = Calendar.getInstance();//数据库时间
//            Calendar current = Calendar.getInstance();//当前时间
//            trayCal.setTime(trayDate);
//            current.setTime(new Date());
//            //如果年份小于二的话先不要改
//            int year = current.get(Calendar.YEAR) - trayCal.get(Calendar.YEAR);
//            if(year >= 2){
//                trayDao.updateOne(Criteria.where("trayNumber").regex(number),new Document("highlight",true));
//            }
//
//        }

//        VtuzxMap data = new VtuzxMap();
//        Iterator<Document> trayItr = trayDao.findList(Criteria.where("rfid").in(rfidList), null, 0, 0);
//        while (trayItr.hasNext()) {
//            Document trayDoc = trayItr.next();
//            List<String> rfid = VtuzxUtil.getObject(trayDoc, "rfid");
//            for (String r: rfid) {
//                data.append(r, trayDoc);
//            }
//        }
//        if (rfidList.size() == 0) {
//            throw new VtuzxException("rfid未绑定托盘");
//        }
//
//        _logger.info(String.format("托盘盘点整理有效的rfid, rfid:%s, timestamp:%d, sign:%s, data:%s", rfidStr, timestamp, sign, data));
//        List<ObjectId> ids = new ArrayList<>();
//        for (String rfid: rfidList) {
//            Document doc = VtuzxUtil.getObject(data, rfid);
//            ObjectId _id = VtuzxUtil.getObject(doc, "_id");
//            ids.add(_id);
//        }
//        _logger.info(String.format("托盘盘点获取需要更新的托盘id成功, rfid:%s, timestamp:%d, sign:%s, ids:%s", rfidStr, timestamp, sign, StringUtils.collectionToCommaDelimitedString(ids)));


    }


    @Override
    public void boxNoBindTray(Map<String, Object> param) throws VtuzxException {
        List<String> rfidList = VtuzxUtil.getObject(param, "rfid_list");
        long timestamp = VtuzxUtil.getLong(param, "timestamp");
        String sign = VtuzxUtil.getString(param, "sign");
        String rfidStr = StringUtils.collectionToCommaDelimitedString(rfidList);
        _logger.info(String.format("箱拖绑定开始, rfid:%s, timestamp:%d, sign:%s", rfidStr, timestamp, sign));
        // 验签
        checkSign(sign, timestamp, rfidStr);
        _logger.info(String.format("箱拖绑定验签通过, rfid:%s, timestamp:%d, sign:%s", rfidStr, timestamp, sign));
        Criteria cond = new Criteria("rfid").in(rfidList).and("inStock").is(false);
        Document trayDoc = trayDao.findOne(Criteria.where("rfid").in(rfidList));
        if (VtuzxUtil.isEmpty(trayDoc)) {
            throw new VtuzxException("不存在托盘码！");
        }
        String trayNumber = VtuzxUtil.getString(trayDoc, "trayNumber");

        inventoryDetailDao.updateMany(Criteria.where("rfid").in(rfidList).and("status").is("in"), new Document("trayNumber", trayNumber));
        purColDetailDao.updateMany(cond, new Document("trayNumber", trayNumber));
        prdColDetailDao.updateMany(cond, new Document("trayNumber", trayNumber));
        otherColDetailDao.updateMany(cond, new Document("trayNumber", trayNumber));
    }

    @Override
    public void boxNoBindTraceBack(Map<String, Object> param) throws VtuzxException {
        long timestamp = VtuzxUtil.getLong(param, "timestamp");
        String sign = VtuzxUtil.getString(param, "sign");
        String key = VtuzxUtil.getString(param, "key");
        String trace_back = VtuzxUtil.getString(param, "trace_back");
        String traceStr = trace_back.substring(trace_back.indexOf("=") + 1);
        _logger.info(String.format("追溯码绑定开始, key:%s, timestamp:%d, trace_back:%s, sign:%s", key, timestamp, traceStr, sign));
        // 验签
        checkSign(sign, timestamp, key, traceStr);
        _logger.info(String.format("追溯码绑定验签通过, key:%s, timestamp:%d, trace_back:%s, sign:%s", key, timestamp, traceStr, sign));
        Criteria cond = new Criteria("traceabilityCode").is(trace_back).and("enableStatus").is(false);
        Document traceabilityCodeDetailDoc = traceabilityCodeDetailDao.findOne(cond);
        if (VtuzxUtil.isEmpty(traceabilityCodeDetailDoc)) {
            throw new VtuzxException("追溯码不存在或已被使用！");
        }
        ObjectId id = VtuzxUtil.getObject(traceabilityCodeDetailDoc, "_id");
        ObjectId traceabilityCodeId = VtuzxUtil.getObject(traceabilityCodeDetailDoc, "_traceabilityCodeId");
        Document document = new Document();
        document.append("enableStatus", true);
        Criteria invCond = new Criteria("status").is("in");
        if (key.startsWith("A")) {
            invCond.and("boxNo").is(key);
            document.append("boxNo", key);
        } else {
            invCond.and("rfid").is(key);
            document.append("rfid", key);
        }

        inventoryDetailDao.updateMany(invCond, new Document("traceBack", traceStr));
        traceabilityCodeDetailDao.updateById(id, document);
        traceabilityCodeDao.updateByIdRedirect(traceabilityCodeId, new Document("$inc", new Document("enabledCount", 1).append("noEnabledCount", -1)));
    }

    @Override
    public void updateStockData(Map<String, Object> param) {
        VtuzxMap mao = new VtuzxMap();
        Iterator<Document> inventoryDetail = inventoryDetailDao.findList(Criteria.where("stockNo").is("012").and("status").is("in"), null, 0, 0);
        while (inventoryDetail.hasNext()) {
            Document invDoc = inventoryDetail.next();
            double count = VtuzxUtil.getDouble(invDoc, "count");
            String inventoryId = VtuzxUtil.getString(invDoc, "_inventoryId");
            Document sum = VtuzxUtil.getObject(mao, inventoryId);
//            double sumCount = VtuzxUtil.getDouble(mao, inventoryId);
            if (sum == null) {
                mao.append(inventoryId, new Document("count", count).append("boxCount", 1));
            } else {
                mao.append(inventoryId, new Document("count", VtuzxUtil.getDouble(sum, "count") + count).append("boxCount", VtuzxUtil.getInt(sum, "boxCount") + 1));
            }
        }
//
//        mao.forEach((k, v) -> {
//            Document map = (Document) v;
//            double count = VtuzxUtil.getDouble(map, "count");
//            int boxCount = VtuzxUtil.getInt(map, "boxCount");
//            inventoryDao.updateById(k, new Document("testCount", count).append("testBoxCount", boxCount));
//        });

        List<String> idList = new ArrayList<>();
        Iterator<Document> invItr = inventoryDao.findList(Criteria.where("stockNo").is("012"), null, 0, 0);
        while (invItr.hasNext()) {
            Document inv = invItr.next();
            String id = VtuzxUtil.getString(inv, "_id");
            idList.add(id);
        }

        for (String id: idList) {
            Document sum = VtuzxUtil.getObject(mao, id);
            if (sum != null) {
                double count = VtuzxUtil.getDouble(sum, "count");
                int boxCount = VtuzxUtil.getInt(sum, "boxCount");
                inventoryDao.updateById(id, new Document("count", count).append("boxCount", boxCount));
            } else {
                inventoryDao.updateById(id, new Document("count", 0.0).append("boxCount", 0));
            }
        }

    }

    @Override
    public ModelAndView traceabilityHistory(Map<String, Object> p, HttpServletRequest req) throws VtuzxException {
        VtuzxMap sysParamMap = settingService.getParameters(new VtuzxMap("keys", new VtuzxArrayList<>("traceabilityRedirectUrl")));
        VtuzxMap traceabilityCodeUrlMap = VtuzxUtil.getObject(sysParamMap, "traceabilityRedirectUrl");
        if (traceabilityCodeUrlMap == null) {
            throw new VtuzxException(IXqcConst.Msg_E_system);
        }
        String value = VtuzxUtil.getString(traceabilityCodeUrlMap, "value");
        String ip = webService.getIp(req);
        String code = VtuzxUtil.getString(p, "traceabilityCode");
        _logger.info("存履历的code:" + code);
        Document detailDoc = inventoryDetailDao.findOne(Criteria.where("traceBack").is(code));
        if (detailDoc == null) {
            throw new VtuzxException("信息不存在");
        }
        ObjectId _inventoryId = VtuzxUtil.getObject(detailDoc, "_inventoryId");

        Document invDoc = inventoryDao.findById(_inventoryId);
        String materialNo = VtuzxUtil.getString(invDoc, "materialNo");
        String batchNo = VtuzxUtil.getString(invDoc, "batchNo");
        Document materialDoc = materialDao.findOne(Criteria.where("fNumber").is(materialNo));
        String materialName = VtuzxUtil.getString(materialDoc, "fName");
        String materialSpec = VtuzxUtil.getString(materialDoc, "fSpecification");

        Document historyDoc = traceabilityHistoryDao.findOne(Criteria.where("code").is(code));
        ObjectId id = null;
        if (historyDoc == null) {
            historyDoc = new Document("code", code)
                    .append("materialNo",materialNo)
                    .append("materialSpec",materialSpec)
                    .append("materialName", materialName)
                    .append("batchNo", batchNo)
                    .append("ip", ip)
                    .append("frequency", 1)
                    .append("lastDate", new Date());
            traceabilityHistoryDao.insertOne(historyDoc);
        } else {
            id = VtuzxUtil.getObject(historyDoc, "_id");
            traceabilityHistoryDao.updateByIdRedirect(id, new Document("$inc", new Document("frequency", 1)).append("$set", new Document("lastDate", new Date())));
        }
        ModelAndView mv = new ModelAndView();
//        String redirectCode =
        mv.setViewName("redirect:" + value + "?traceabilityCode=" + code);
        return mv;
    }

    @Override
    public VtuzxMap getTraceabilityHistoryList(ObjectId userId, String name, Map<String, Object> param) {
        int pageSize = VtuzxUtil.getInt(param, IVtuzxConst.Key_pageSize);
        int pageIndex = VtuzxUtil.getInt(param, IVtuzxConst.Key_pageIndex);
        String code = VtuzxUtil.getString(param, "code");
        String materialNo = VtuzxUtil.getString(param, "materialNo");
        Criteria cond = new Criteria();
        if (!VtuzxUtil.isEmpty(code)) {
            cond.and("code").regex(code);
        }
        if (!VtuzxUtil.isEmpty(materialNo)) {
            cond.and("materialNo").regex(materialNo);
        }
        VtuzxPage page = traceabilityHistoryDao.page(cond, new Document("createTime", -1), pageIndex, pageSize);
        List<VtuzxMap> dataList = page.iterator(doc -> new VtuzxMap("id", VtuzxUtil.getString(doc, IVtuzxConst.Key__id))
                .append("code", VtuzxUtil.getString(doc, "code"))
                .append("materialNo", VtuzxUtil.getString(doc, "materialNo"))
                .append("materialSpec", VtuzxUtil.getString(doc, "materialSpec"))
                .append("materialName", VtuzxUtil.getString(doc, "materialName"))
                .append("batchNo", VtuzxUtil.getString(doc, "batchNo"))
                .append("ip", VtuzxUtil.getString(doc, "ip"))
                .append("frequency", VtuzxUtil.getInt(doc, "frequency"))
                .append("lastDate", VtuzxUtil.formatYmdHmsF(VtuzxUtil.getObject(doc, "lastDate"))));
        return new VtuzxMap(IVtuzxConst.Key_total, page.total()).append(IVtuzxConst.Key_data, dataList);
    }

    @Override
    public VtuzxMap setNoPrintBoxNoFlag(Map<String, Object> param) throws VtuzxException {
        String printFlag = VtuzxUtil.getString(param, "print_flag");
        long timestamp = VtuzxUtil.getLong(param, "timestamp");
        String sign = VtuzxUtil.getString(param, "sign");
        _logger.info(String.format("RFID绑码开始, userName:%s, timestamp:%d, sign:%s", printFlag, timestamp, sign));
        // 验签
        checkSign(sign, timestamp, printFlag);
        _logger.info(String.format("RFID绑码验签通过, userName:%s, timestamp:%d, sign:%s", printFlag, timestamp, sign));

        configDao.setPrintFlag("1".equals(printFlag));

        return null;
    }

    @Override
    public VtuzxMap getNoPrintBoxNo(Map<String, Object> param) throws VtuzxException {
        BillType billType = BillType.SCRK;
        String userName = VtuzxUtil.getString(param, "user_name");
        long timestamp = VtuzxUtil.getLong(param, "timestamp");
        String sign = VtuzxUtil.getString(param, "sign");
        _logger.info(String.format("RFID绑码开始, userName:%s, timestamp:%d, sign:%s", userName, timestamp, sign));
        // 验签
        checkSign(sign, timestamp, userName);
        _logger.info(String.format("RFID绑码验签通过, userName:%s, timestamp:%d, sign:%s", userName, timestamp, sign));

//        boolean printFlag = configDao.getPrintFlag();
//        if (!printFlag) {
//            throw new VtuzxException("打印关闭中");
//        }

        if ("test".equals(userName)) {
            VtuzxMap dataMap = new VtuzxMap("materialNo", "04030303001")
                    .append("materialName", "晓芹特级冷冻海参/B款")
                    .append("materialSpec", "7-10头/500g")
                    .append("count", 60.0)
                    .append("boxCount", 1)
                    .append("createTime", VtuzxUtil.formatYmdHmsF(new Date()))
                    .append("comment", "")
                    .append("batchNo", "121026")
                    .append("boxNo", "A021673245584715")
                    .append("barcode", billType.barcodeKey() + "|;" + "63bbdade2b3fc45ce5556e2a" + "|;" + "04030303001" + "|;" + "121026" + "|;" + "60.0" + "|;" + "A021673245584715")
                    .append("insertUserName", "test")
                    .append("department", "外包装车间1");
            return new VtuzxMap(IVtuzxConst.Key_data, dataMap);
        }

        VtuzxMap dataMap = new VtuzxMap();
        Iterator<Document> prdColDetailDocItr = prdColDetailDao.findList(Criteria.where("insertUserName").is(userName).and("noPrint").is(true), new Document("createTime", 1), 0, 0);
        while (prdColDetailDocItr.hasNext()) {
            Document colDoc = prdColDetailDocItr.next();
            double standard = VtuzxUtil.getDouble(colDoc, "standard");
            List<String> traceBack = VtuzxUtil.getObject(colDoc, "traceBack");
            boolean isTemp = VtuzxUtil.getBoolean(colDoc, "isTemp");
            String billNo = VtuzxUtil.getString(colDoc, "billNo");
            String batchNo = VtuzxUtil.getString(colDoc, "batchNo");
            double traceBackSize = traceBack.size();
            if (((standard == traceBackSize && isTemp && standard > 0) && !VtuzxUtil.isEmpty(batchNo)) || !VtuzxUtil.isEmpty(billNo)) {
                String id = VtuzxUtil.getString(colDoc, "_id");
                String materialNo = VtuzxUtil.getString(colDoc, "materialNo");
                Document materialDoc = materialDao.findOne(Criteria.where("fNumber").is(materialNo));
                if (VtuzxUtil.isEmpty(materialDoc)) {
                    throw new VtuzxException("物料不存在");
                }
                String materialName = VtuzxUtil.getString(materialDoc, "fName");
                String materialSpec = VtuzxUtil.getString(materialDoc, "fSpecification");
                double count = VtuzxUtil.getDouble(colDoc, "count");
                String comment = VtuzxUtil.getString(colDoc, "comment");
                String produceDate = VtuzxUtil.getString(colDoc,"produceDate");
                String boxNo = VtuzxUtil.getString(colDoc, "boxNo");
                String insertUserName = VtuzxUtil.getString(colDoc, "insertUserName");
                String department = VtuzxUtil.getString(colDoc, "department");
                int orderNum = VtuzxUtil.getInt(colDoc, "orderNum");


                dataMap.append("materialNo", materialNo)
                        .append("materialName", materialName)
                        .append("materialSpec", materialSpec)
                        .append("count", count)
                        .append("boxCount", 1)
                        .append("createTime", VtuzxUtil.formatYmdHmsF(new Date()))
                        .append("comment", produceDate)
                        .append("batchNo", batchNo)
                        .append("barcode", billType.barcodeKey() + "|;" + id + "|;" + materialNo + "|;" + "888888" + "|;" + count + "|;" + boxNo)
                        .append("boxNo", boxNo)
                        .append("insertUserName", insertUserName)
                        .append("department", department)
                        .append("orderNum", orderNum);

                prdColDetailDao.updateOne(Criteria.where("boxNo").is(boxNo), new Document("noPrint", false));
            }
            if (dataMap.size() != 0) {
                return new VtuzxMap(IVtuzxConst.Key_data, dataMap);
            }
        }
        throw new VtuzxException("不存在未打印箱号");
    }

    @Override
    public VtuzxMap getSaleByDealer(Map<String, Object> param) throws Exception {
        String startTime = VtuzxUtil.getString(param,"startTime");
        String endTime = VtuzxUtil.getString(param,"endTime");
        String dealer = VtuzxUtil.getString(param,"dealer");//经销商
        String pageIndex = VtuzxUtil.getString(param,"pageIndex");
        Document storeDoc = storeTokenDao.findOne(Criteria.where("type").is("kingdee"));
        //先根据经销商查询渠道id(经销商对应销售单里销售渠道)
        VtuzxMap dealerMap = jiKeYunApiService.getDealer(storeDoc,
                new VtuzxMap("pageSize",1).append("name",dealer));
        Map<String, Object> dealerResult = VtuzxUtil.getObject(dealerMap, "result");
        Map<String, Object> dealerData = VtuzxUtil.getObject(dealerResult, "data");
        List<Map<String, Object>> salesChannelInfo = VtuzxUtil.getObject(dealerData, "salesChannelInfo");
        Map<String,Object> saleChannel = salesChannelInfo.get(0);
        String channelId = VtuzxUtil.getString(saleChannel,"channelId");//销售渠道id

        //直接调极客云接口查询

        VtuzxMap customerMap = jiKeYunApiService.getSaleBill(storeDoc,
                new VtuzxMap("startCreated", startTime)//创建时间
                        .append("endCreated", endTime)//创建时间
                        .append("pageSize", 50)
                        .append("shopIds",channelId)
                        .append("pageIndex", pageIndex)
                        .append("fields", "shopName,tradeNo,tradeStatus,warehouseCode,shopName,flagIds,sysFlagIds,flagNames,tradeCount,shareFavourableFee,warehouseCode,sellerMemo"));
        Map<String, Object> result = VtuzxUtil.getObject(customerMap, "result");
        Map<String, Object> data = VtuzxUtil.getObject(result, "data");
        List<Map<String, Object>> trades = VtuzxUtil.getObject(data, "trades");

        VtuzxMap dataMap = new VtuzxMap();//返回的数据
        dataMap.append("data",trades);
        return dataMap;
    }

    @Override
    public VtuzxMap getSaleByTradeNo(Map<String, Object> param) throws Exception {
        String tradeNo = VtuzxUtil.getString(param,"tradeNo");
        Document storeDoc = storeTokenDao.findOne(Criteria.where("type").is("kingdee"));
//        String userName = VtuzxUtil.getString(param, "user_name");
//        long timestamp = VtuzxUtil.getLong(param, "timestamp");
//        String sign = VtuzxUtil.getString(param, "sign");
        // 验签
//        checkSign(sign, timestamp, userName);
        _logger.info(String.format("单号%s，查询销售单明细",tradeNo));
        //直接调极客云接口查询
        VtuzxMap dataMap = new VtuzxMap();//返回数据
        VtuzxMap customerMap = jiKeYunApiService.getSaleBill(storeDoc,
                new VtuzxMap("tradeNo", tradeNo)
                        .append("fields", "goodsSerial.skuId,goodsSerial.subTradeId,goodsSerial.serialNo,warehouseName,warehouseCode,customerCode,goodsDetail.goodsNo,goodsDelivery.productionDate,goodsDelivery.expirationDate,goodsDelivery.batchNo,tradeNo,tradeStatus,warehouseCode,shopName,flagIds,sysFlagIds,flagNames,tradeCount,shareFavourableFee,warehouseCode,goodsDetail.unit,goodsDetail.goodsNo,goodsDetail.goodsName,goodsDetail.specName,goodsDetail.sellCount,goodsDetail.sellPrice,goodsDetail.taxRate,sellerMemo,goodsDelivery.batchNo"));
        Map<String, Object> tradeResult = VtuzxUtil.getObject(customerMap, "result");
        String tradeString = VtuzxUtil.getString(tradeResult,"data");
        Map<String,Object> tradeData = JSON.parseObject(tradeString,new TypeReference<HashMap<String,Object>>(){});
        JSONArray jsonArray = VtuzxUtil.getObject(tradeData,"Trades");
        JSONObject jsonTrades = (JSONObject) jsonArray.get(0);
        Map<String,Object> tradeMap = new HashMap<>();
        for (Map.Entry<String,Object> entry : jsonTrades.entrySet()){
            tradeMap.put(entry.getKey(),entry.getValue());
        }
        List<Map<String,Object>> goodsSerials = VtuzxUtil.getObject(tradeMap,"goodsSerials");
        List<Map<String,Object>> goodsDetail = VtuzxUtil.getObject(tradeMap,"goodsDetail");
        if(!VtuzxUtil.isEmpty(goodsSerials)){
            for (Map<String,Object> map : goodsSerials){//找出追溯码对应的信息
                String serialNo = VtuzxUtil.getString(map,"serialNo");
                if (!VtuzxUtil.isEmpty(serialNo)){
                    StringBuilder sb = new StringBuilder(serialNo.toLowerCase());
                    sb.setCharAt(49,'Z');
                    sb.setCharAt(44,'C');
                    String newSerialNo = sb.toString();
                    Map<String,Object> serialMap = new HashMap<>();
                    serialMap.put("traceabilityCode",newSerialNo);
                    //调用接口获取唯一码信息
                    VtuzxMap traceBackCodeData = iXqcTraceBackService.getTraceBackCodeData(serialMap);
                    map.put("serialMap",traceBackCodeData);
                }
            }
        } else {
            dataMap.put("message","单号未出库或者是组合装，无法查看唯一码");
        }
        if (!VtuzxUtil.isEmpty(goodsSerials)){
            for (Map<String,Object> map : goodsSerials){//把唯一码放到对应的品下面
                String subTradeId = VtuzxUtil.getString(map,"subTradeId");
                for (Map<String,Object> goodsMap : goodsDetail){
                    String goodsSubTradeId = VtuzxUtil.getString(goodsMap,"subTradeId");
                    if (subTradeId.equals(goodsSubTradeId)){
                        goodsMap.put("goodsSerial",map);
                        break;
                    }
                }
            }
            tradeMap.remove("goodsSerials");
        }
        dataMap.append("data",tradeMap);
        return dataMap;
    }

    @Override
    public VtuzxMap getPackageList(Map<String, Object> param) throws Exception {
        String startTime = VtuzxUtil.getString(param,"startTime");
        String endTime = VtuzxUtil.getString(param,"endTime");
        String pageIndex = VtuzxUtil.getString(param,"pageIndex");
        int state = VtuzxUtil.getInt(param,"state");
        Document storeDoc = storeTokenDao.findOne(Criteria.where("type").is("kingdee"));
        List<Map<String,Object>> dataList = new ArrayList<>();//返回的信息
        if(state == 0){//0：发货单状态未完成
            //根据时间查询包裹信息
            List<Integer> numList = new ArrayList<>();//单号状态
            numList.add(1);
            VtuzxMap orderMap = jiKeYunApiService.getSaleOrderInfo(storeDoc,
                    new VtuzxMap("startGmtCreate",startTime)
                            .append("endGmtCreate",endTime)
                            .append("orderStatusList",numList)
                            .append("pageIndex",pageIndex)
            );
            Map<String, Object> orderResult = VtuzxUtil.getObject(orderMap, "result");
            List<Map<String, Object>> orderData = VtuzxUtil.getObject(orderResult, "data");
//        List<Map<String, Object>> orderInfo = VtuzxUtil.getObject(orderData, "salesChannelInfo");
            //循环发货信息，查询发货包裹
            for (Map<String,Object> order : orderData){
                String orderNo = VtuzxUtil.getString(order,"orderNo");
                VtuzxMap packageMap = jiKeYunApiService.getPackageListByOrderNo(storeDoc,
                        new VtuzxMap("orderNo",orderNo));
                Map<String, Object> packageResult = VtuzxUtil.getObject(packageMap, "result");
                List<Map<String, Object>> packageData = VtuzxUtil.getObject(packageResult, "data");
                if (!VtuzxUtil.isEmpty(packageData)){
                    Map<String, Object> packageInfo = packageData.get(0);
                    List<Map<String,Object>> packDetailList = VtuzxUtil.getObject(packageInfo,"packDetailList");
                    if (!VtuzxUtil.isEmpty(packDetailList)){//说明已经拆包了把信息放到返回的list里
                        dataList.add(packageInfo);
                    }
                }

            }
        } else if (state == 1){//1:状态已完成的
            //根据时间查询包裹信息(状态已完成的)
            List<Integer> numList = new ArrayList<>();//单号状态
            numList.add(7);
            VtuzxMap orderMap = jiKeYunApiService.getSaleOrderInfoFinish(storeDoc,
                    new VtuzxMap("startFinishTime",startTime)
                            .append("endFinishTime",endTime)
                            .append("orderStatusList",numList)
                            .append("pageIndex",pageIndex)
            );
            Map<String, Object> orderResult = VtuzxUtil.getObject(orderMap, "result");
            List<Map<String, Object>> orderData = VtuzxUtil.getObject(orderResult, "data");
            //循环发货信息，查询发货包裹
            for (Map<String,Object> order : orderData){
                String orderNo = VtuzxUtil.getString(order,"orderNo");
                VtuzxMap packageMap = jiKeYunApiService.getPackageListByOrderNo(storeDoc,
                        new VtuzxMap("orderNo",orderNo));
                Map<String, Object> packageResult = VtuzxUtil.getObject(packageMap, "result");
                List<Map<String, Object>> packageData = VtuzxUtil.getObject(packageResult, "data");
                if (!VtuzxUtil.isEmpty(packageData)){
                    Map<String, Object> packageInfo = packageData.get(0);
                    List<Map<String,Object>> packDetailList = VtuzxUtil.getObject(packageInfo,"packDetailList");
                    if (!VtuzxUtil.isEmpty(packDetailList)){//说明已经拆包了把信息放到返回的list里
                        dataList.add(packageInfo);
                    }
                }

            }
        }


        return new VtuzxMap("data",dataList);
    }

    @Override
    public VtuzxMap getPackageByOrderNo(Map<String,Object> param) throws Exception {
        String tradeNo = VtuzxUtil.getString(param,"tradeNo");
        Document storeDoc = storeTokenDao.findOne(Criteria.where("type").is("kingdee"));

        VtuzxMap dataMap = new VtuzxMap();//返回的信息
        //先查询销售单获取发货单号
        VtuzxMap saleMap = jiKeYunApiService.getSaleBill(storeDoc,
                new VtuzxMap()
                        .append("tradeNo",tradeNo)
                        .append("pageSize", 1)
                        .append("pageIndex", 0)
                        .append("fields", "stockoutNo,orderNo,onlineTradeNo,appendMemo,buyerMemo,sellerMemo,otherFee,discountFee,isFit,isGift,goodsMemo,tradeFrom,consignTime,goodsSerial.subTradeId,goodsSerial.skuId,goodsSerial.serialNo,warehouseName,warehouseCode,customerCode,goodsDetail.goodsNo,goodsDelivery.productionDate,goodsDelivery.expirationDate,goodsDelivery.batchNo,tradeNo,tradeStatus,warehouseCode,shopName,flagIds,sysFlagIds,flagNames,tradeCount,shareFavourableFee,warehouseCode,goodsDetail.unit,goodsDetail.goodsNo,goodsDetail.goodsName,goodsDetail.specName,goodsDetail.sellCount,goodsDetail.sellPrice,goodsDetail.taxRate,sellerMemo,goodsDelivery.batchNo,goodsSerial.serialNo"));

        Map<String, Object> tradeResult = VtuzxUtil.getObject(saleMap, "result");

        String tradeString = VtuzxUtil.getString(tradeResult,"data");
        Map<String,Object> tradeData = JSON.parseObject(tradeString,new TypeReference<HashMap<String,Object>>(){});
        JSONArray jsonArray = VtuzxUtil.getObject(tradeData,"Trades");
        JSONObject jsonTrades = (JSONObject) jsonArray.get(0);
        Map<String,Object> tradeMap = new HashMap<>();
        for (Map.Entry<String,Object> entry : jsonTrades.entrySet()){
            tradeMap.put(entry.getKey(),entry.getValue());
        }

        String orderNo = VtuzxUtil.getString(tradeMap,"OrderNo");
        List<Map<String,Object>> goodsDetail = VtuzxUtil.getObject(tradeMap,"GoodsDetail");
        dataMap.append("tradeData",goodsDetail);

        VtuzxMap packageMap = jiKeYunApiService.getPackageListByOrderNo(storeDoc,
                new VtuzxMap("orderNo",orderNo));
        Map<String, Object> packageResult = VtuzxUtil.getObject(packageMap, "result");
        List<Map<String, Object>> packageData = VtuzxUtil.getObject(packageResult, "data");
        if (!VtuzxUtil.isEmpty(packageData)){
           dataMap.append("packageData",packageData);
        } else {
            dataMap.append("packageData","当前单号未发货");
        }

        return dataMap;
    }

    /**
     * 绑定追溯链信息(思迅传过来)
     * @param param
     * @return
     * @throws Exception
     */
    @Override
    public Boolean bindingSerial(Map<String, Object> param) throws Exception {

        long timestamp = VtuzxUtil.getLong(param, "timestamp");
        String sign = VtuzxUtil.getString(param, "sign");
        List<Map<String,Object>> dataList = new ArrayList<>();
        _logger.info(String.format("思迅修改追溯信息开始,  timestamp:%d, sign:%s", timestamp, sign));
        //验签
        checkSign(sign,timestamp,"dataList");
        _logger.info(String.format("思迅修改追溯信息验签完成,  timestamp:%d, sign:%s", timestamp, sign));
        for (Map<String,Object> data : dataList){
            String type = VtuzxUtil.getString(data,"type");
            //根据类型判断是调拨还是销售
            if("trade".equals(type)){//销售单
                String saleChnnel = VtuzxUtil.getString(data,"saleChnnel");//销售渠道
                String saleTime = VtuzxUtil.getString(data,"saleTime");//发货时间
                String tradeNo = VtuzxUtil.getString(data,"tradeNo");//销售单号
                List<String> serialNoList = VtuzxUtil.getObject(data,"serialNoList");//追溯码集合
                Document updateDoc = new Document();
                updateDoc.append("saleChnnel", saleChnnel)//销售渠道
                        .append("saleTime", saleTime)//发货时间
                        .append("lastTime", saleTime)//最后操作时间
                        .append("tradeNo", tradeNo);
                _logger.info(String.format("添加追溯链信息[%s]", serialNoList));
                traceabilityCodeDetailDao.updateMany(Criteria.where("traceabilityCode").in(serialNoList),updateDoc);
            } else if ("allocation".equals(type)){
                String issue = VtuzxUtil.getString(data,"issue");//发出仓库
                String saleChnnel = VtuzxUtil.getString(data,"saleChnnel");//销售渠道
                String gmtCreate = VtuzxUtil.getString(data,"gmtCreate");//调拨单创建时间
                String allocationNo = VtuzxUtil.getString(data,"allocationNo");//调拨单号
                String receive = VtuzxUtil.getString(data,"receive");//调入仓库
                List<String> serialNoList = VtuzxUtil.getObject(data,"serialNoList");//追溯码集合
                Document serialDoc = new Document();
                serialDoc.append("issue",issue)//发出方对应出库仓库
                        .append("saleChnnel",receive)//销售渠道（对应调入仓库）
                        .append("lastTime",gmtCreate)//销售时间
                        .append("allocateTime",gmtCreate)//调拨时间
                        .append("allocateNo",allocationNo)
                        .append("receive",receive);//接收方对应调入仓库
                _logger.info(String.format("添加追溯链信息[%s]", serialNoList));
                traceabilityCodeDetailDao.updateMany(Criteria.where("traceabilityCode").in(serialNoList),serialDoc);
            }
        }
        return true;
    }
}
